Add support for BL2 in XIP memory
authorJiafei Pan <[email protected]>
Wed, 21 Mar 2018 07:20:09 +0000 (07:20 +0000)
committerJiafei Pan <[email protected]>
Sat, 7 Apr 2018 02:12:21 +0000 (10:12 +0800)
In some use-cases BL2 will be stored in eXecute In Place (XIP) memory,
like BL1. In these use-cases, it is necessary to initialize the RW sections
in RAM, while leaving the RO sections in place. This patch enable this
use-case with a new build option, BL2_IN_XIP_MEM. For now, this option
is only supported when BL2_AT_EL3 is 1.

Signed-off-by: Jiafei Pan <[email protected]>
Makefile
bl2/bl2_el3.ld.S
bl2/bl2_private.h
docs/porting-guide.rst
docs/user-guide.rst
include/common/aarch64/el3_common_macros.S
include/plat/common/common_def.h
make_helpers/defaults.mk

index ef4e5c6815841a9ad1c3e2db45d0826fb26df42e..a8378462bf81b62362302fa94448d6d728632bf0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -373,6 +373,11 @@ ifneq ($(MULTI_CONSOLE_API), 0)
     endif
 endif
 
+#For now, BL2_IN_XIP_MEM is only supported when BL2_AT_EL3 is 1.
+ifeq ($(BL2_AT_EL3)-$(BL2_IN_XIP_MEM),0-1)
+$(error "BL2_IN_XIP_MEM is only supported when BL2_AT_EL3 is enabled")
+endif
+
 ################################################################################
 # Process platform overrideable behaviour
 ################################################################################
@@ -518,6 +523,7 @@ $(eval $(call assert_boolean,USE_COHERENT_MEM))
 $(eval $(call assert_boolean,USE_TBBR_DEFS))
 $(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY))
 $(eval $(call assert_boolean,BL2_AT_EL3))
+$(eval $(call assert_boolean,BL2_IN_XIP_MEM))
 
 $(eval $(call assert_numeric,ARM_ARCH_MAJOR))
 $(eval $(call assert_numeric,ARM_ARCH_MINOR))
@@ -564,6 +570,7 @@ $(eval $(call add_define,USE_COHERENT_MEM))
 $(eval $(call add_define,USE_TBBR_DEFS))
 $(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))
 $(eval $(call add_define,BL2_AT_EL3))
+$(eval $(call add_define,BL2_IN_XIP_MEM))
 
 # Define the EL3_PAYLOAD_BASE flag only if it is provided.
 ifdef EL3_PAYLOAD_BASE
index 3728643caee3884f49f5c8dcbc46be18116565e2..0f91edc952e720c93ece12b0994247f22bb126de 100644 (file)
@@ -12,15 +12,26 @@ OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
 ENTRY(bl2_entrypoint)
 
 MEMORY {
+#if BL2_IN_XIP_MEM
+    ROM (rx): ORIGIN = BL2_RO_BASE, LENGTH = BL2_RO_LIMIT - BL2_RO_BASE
+    RAM (rwx): ORIGIN = BL2_RW_BASE, LENGTH = BL2_RW_LIMIT - BL2_RW_BASE
+#else
     RAM (rwx): ORIGIN = BL2_BASE, LENGTH = BL2_LIMIT - BL2_BASE
+#endif
 }
 
 
 SECTIONS
 {
+#if BL2_IN_XIP_MEM
+    . = BL2_RO_BASE;
+    ASSERT(. == ALIGN(PAGE_SIZE),
+           "BL2_RO_BASE address is not aligned on a page boundary.")
+#else
     . = BL2_BASE;
     ASSERT(. == ALIGN(PAGE_SIZE),
            "BL2_BASE address is not aligned on a page boundary.")
+#endif
 
 #if SEPARATE_CODE_AND_RODATA
     .text . : {
@@ -33,7 +44,11 @@ SECTIONS
         *(.vectors)
         . = NEXT(PAGE_SIZE);
         __TEXT_END__ = .;
+#if BL2_IN_XIP_MEM
+     } >ROM
+#else
      } >RAM
+#endif
 
     .rodata . : {
         __RODATA_START__ = .;
@@ -56,7 +71,11 @@ SECTIONS
 
         . = NEXT(PAGE_SIZE);
         __RODATA_END__ = .;
+#if BL2_IN_XIP_MEM
+    } >ROM
+#else
     } >RAM
+#endif
 
     ASSERT(__TEXT_RESIDENT_END__ - __TEXT_RESIDENT_START__ <= PAGE_SIZE,
           "Resident part of BL2 has exceeded its limit.")
@@ -95,12 +114,22 @@ SECTIONS
         . = NEXT(PAGE_SIZE);
 
         __RO_END__ = .;
+#if BL2_IN_XIP_MEM
+    } >ROM
+#else
     } >RAM
+#endif
 #endif
 
     ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
           "cpu_ops not defined for this platform.")
 
+#if BL2_IN_XIP_MEM
+    . = BL2_RW_BASE;
+    ASSERT(BL2_RW_BASE == ALIGN(PAGE_SIZE),
+           "BL2_RW_BASE address is not aligned on a page boundary.")
+#endif
+
     /*
      * Define a linker symbol to mark start of the RW memory area for this
      * image.
@@ -113,10 +142,14 @@ SECTIONS
      * section can be placed independently of the main .data section.
      */
     .data . : {
-        __DATA_START__ = .;
+        __DATA_RAM_START__ = .;
         *(.data*)
-        __DATA_END__ = .;
+        __DATA_RAM_END__ = .;
+#if BL2_IN_XIP_MEM
+    } >RAM AT>ROM
+#else
     } >RAM
+#endif
 
     stacks (NOLOAD) : {
         __STACKS_START__ = .;
@@ -174,12 +207,32 @@ SECTIONS
     __RW_END__ = .;
     __BL2_END__ = .;
 
+#if BL2_IN_XIP_MEM
+    __BL2_RAM_START__ = ADDR(.data);
+    __BL2_RAM_END__ = .;
+
+    __DATA_ROM_START__ = LOADADDR(.data);
+    __DATA_SIZE__ = SIZEOF(.data);
+
+    /*
+     * The .data section is the last PROGBITS section so its end marks the end
+     * of BL2's RO content in XIP memory..
+     */
+    __BL2_ROM_END__ =  __DATA_ROM_START__ + __DATA_SIZE__;
+    ASSERT(__BL2_ROM_END__ <= BL2_RO_LIMIT,
+           "BL2's RO content has exceeded its limit.")
+#endif
     __BSS_SIZE__ = SIZEOF(.bss);
 
+
 #if USE_COHERENT_MEM
     __COHERENT_RAM_UNALIGNED_SIZE__ =
         __COHERENT_RAM_END_UNALIGNED__ - __COHERENT_RAM_START__;
 #endif
 
+#if BL2_IN_XIP_MEM
+    ASSERT(. <= BL2_RW_LIMIT, "BL2's RW content has exceeded its limit.")
+#else
     ASSERT(. <= BL2_LIMIT, "BL2 image has exceeded its limit.")
+#endif
 }
index 50295d674fdf8433af8690481e13d0e00be1aca5..f93a179d1373a3ba3b6626ac1a2c070c1ea74f20 100644 (file)
@@ -7,6 +7,20 @@
 #ifndef __BL2_PRIVATE_H__
 #define __BL2_PRIVATE_H__
 
+#if BL2_IN_XIP_MEM
+/*******************************************************************************
+ * Declarations of linker defined symbols which will tell us where BL2 lives
+ * in Trusted ROM and RAM
+ ******************************************************************************/
+extern uintptr_t __BL2_ROM_END__;
+#define BL2_ROM_END (uintptr_t)(&__BL2_ROM_END__)
+
+extern uintptr_t __BL2_RAM_START__;
+extern uintptr_t __BL2_RAM_END__;
+#define BL2_RAM_BASE (uintptr_t)(&__BL2_RAM_START__)
+#define BL2_RAM_LIMIT (uintptr_t)(&__BL2_RAM_END__)
+#endif
+
 /******************************************
  * Forward declarations
  *****************************************/
index ff5bb1225a09d1e9f5a3398a79c44469b6e540e6..12e135f71400774e57c706ab29cb1d10b3ea7272 100644 (file)
@@ -217,11 +217,37 @@ platform port to define additional platform porting constants in
 -  **#define : BL2\_BASE**
 
    Defines the base address in secure RAM where BL1 loads the BL2 binary image.
-   Must be aligned on a page-size boundary.
+   Must be aligned on a page-size boundary. This constant is not applicable
+   when BL2_IN_XIP_MEM is set to '1'.
 
 -  **#define : BL2\_LIMIT**
 
    Defines the maximum address in secure RAM that the BL2 image can occupy.
+   This constant is not applicable when BL2_IN_XIP_MEM is set to '1'.
+
+-  **#define : BL2\_RO\_BASE**
+
+   Defines the base address in secure XIP memory where BL2 RO section originally
+   lives. Must be aligned on a page-size boundary. This constant is only needed
+   when BL2_IN_XIP_MEM is set to '1'.
+
+-  **#define : BL2\_RO\_LIMIT**
+
+   Defines the maximum address in secure XIP memory that BL2's actual content
+   (i.e. excluding any data section allocated at runtime) can occupy. This
+   constant is only needed when BL2_IN_XIP_MEM is set to '1'.
+
+-  **#define : BL2\_RW\_BASE**
+
+   Defines the base address in secure RAM where BL2's read-write data will live
+   at runtime. Must be aligned on a page-size boundary. This constant is only
+   needed when BL2_IN_XIP_MEM is set to '1'.
+
+-  **#define : BL2\_RW\_LIMIT**
+
+   Defines the maximum address in secure RAM that BL2's read-write data can
+   occupy at runtime. This constant is only needed when BL2_IN_XIP_MEM is set
+   to '1'.
 
 -  **#define : BL31\_BASE**
 
index 579485546e0b224498f55536397e95658ef8a697..fdf1568e185d3895811e1ca62be3364c02cc362a 100644 (file)
@@ -246,6 +246,12 @@ Common build options
 - ``BL2_AT_EL3``: This is an optional build option that enables the use of
    BL2 at EL3 execution level.
 
+- ``BL2_IN_XIP_MEM``: In some use-cases BL2 will be stored in eXecute In Place
+   (XIP) memory, like BL1. In these use-cases, it is necessary to initialize
+   the RW sections in RAM, while leaving the RO sections in place. This option
+   enable this use-case. For now, this option is only supported when BL2_AT_EL3
+   is set to '1'.
+
 -  ``BL31``: This is an optional build option which specifies the path to
    BL31 image for the ``fip`` target. In this case, the BL31 in TF-A will not
    be built.
index 4ebf77bbf1ca950a88098082cf8cd7f77c0573df..e85249c418c6576e6f72d4766f461a866b90ccf0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
                bl      zeromem
 #endif
 
-#ifdef IMAGE_BL1
+#if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && BL2_IN_XIP_MEM)
                ldr     x0, =__DATA_RAM_START__
                ldr     x1, =__DATA_ROM_START__
                ldr     x2, =__DATA_SIZE__
index 84923b9a77221e78f165e82387e2c6737a781160..827d416f34a3321458b6a2246f47e38daa65ba58 100644 (file)
 #define BL1_CODE_END           BL_CODE_END
 #define BL1_RO_DATA_BASE       BL_RO_DATA_BASE
 #define BL1_RO_DATA_END                round_up(BL1_ROM_END, PAGE_SIZE)
+#if BL2_IN_XIP_MEM
+#define BL2_CODE_END           BL_CODE_END
+#define BL2_RO_DATA_BASE       BL_RO_DATA_BASE
+#define BL2_RO_DATA_END                round_up(BL2_ROM_END, PAGE_SIZE)
+#endif /* BL2_IN_XIP_MEM */
 #else
 #define BL_RO_DATA_BASE                0
 #define BL_RO_DATA_END         0
 #define BL1_CODE_END           round_up(BL1_ROM_END, PAGE_SIZE)
+#if BL2_IN_XIP_MEM
+#define BL2_RO_DATA_BASE       0
+#define BL2_RO_DATA_END                0
+#define BL2_CODE_END           round_up(BL2_ROM_END, PAGE_SIZE)
+#endif /* BL2_IN_XIP_MEM */
 #endif /* SEPARATE_CODE_AND_RODATA */
 #endif /* __COMMON_DEF_H__ */
index 751f8343c6de45e118948da90ec0fb57716172e0..77eb157c69f5282e230ff2afbdb49cc9765355ca 100644 (file)
@@ -30,6 +30,10 @@ BASE_COMMIT                  := origin/master
 # Execute BL2 at EL3
 BL2_AT_EL3                     := 0
 
+# BL2 image is stored in XIP memory, for now, this option is only supported
+# when BL2_AT_EL3 is 1.
+BL2_IN_XIP_MEM                 := 0
+
 # By default, consider that the platform may release several CPUs out of reset.
 # The platform Makefile is free to override this value.
 COLD_BOOT_SINGLE_CPU           := 0